package io.gitee.tziye.core.search;

import io.gitee.tziye.common.RenaiUtil;
import io.gitee.tziye.enums.SearchType;

import java.util.ArrayList;
import java.util.List;

public class RenaiBoolSearch<T> {

    private final RenaiSearch<T> renaiSearch;
    private final List<SearchOps> ops;

    public RenaiBoolSearch(RenaiSearch<T> renaiSearch) {
        this.renaiSearch = renaiSearch;
        ops = new ArrayList<>();
    }

    public RenaiBoolSearch<T> match(String word) {
        ops.add(new SearchOps(SearchType.bool_match, List.of(word)));
        return this;
    }

    public RenaiBoolSearch<T> match(List<String> words) {
        ops.add(new SearchOps(SearchType.bool_match, words));
        return this;
    }

    public RenaiBoolSearch<T> must(String word) {
        ops.add(new SearchOps(SearchType.bool_must, List.of(word)));
        return this;
    }

    public RenaiBoolSearch<T> must(List<String> words) {
        ops.add(new SearchOps(SearchType.bool_must, words));
        return this;
    }

    public RenaiBoolSearch<T> mustNot(String word) {
        ops.add(new SearchOps(SearchType.bool_mustNot, List.of(word)));
        return this;
    }

    public RenaiBoolSearch<T> mustNot(List<String> words) {
        ops.add(new SearchOps(SearchType.bool_mustNot, words));
        return this;
    }

    public RenaiBoolSearch<T> startWith(String word) {
        ops.add(new SearchOps(SearchType.bool_startWith, List.of(word)));
        return this;
    }

    public RenaiBoolSearch<T> startWith(List<String> words) {
        ops.add(new SearchOps(SearchType.bool_startWith, words));
        return this;
    }

    public RenaiBoolSearch<T> lower(String word) {
        ops.add(new SearchOps(SearchType.bool_lower, List.of(word)));
        return this;
    }

    public RenaiBoolSearch<T> lower(List<String> words) {
        ops.add(new SearchOps(SearchType.bool_lower, words));
        return this;
    }

    public List<T> exec() {
        List<RenaiText> result = renaiSearch.searchOperator.search(renaiSearch.module, ops, true, 0, 100);
        return result.stream().map(r -> RenaiUtil.parse(r.getContent(), renaiSearch.clazz)).toList();
    }

    public List<T> exec(int start, int count) {
        List<RenaiText> result = renaiSearch.searchOperator.search(renaiSearch.module, ops, true, start, count);
        return result.stream().map(r -> RenaiUtil.parse(r.getContent(), renaiSearch.clazz)).toList();
    }

    public List<RenaiText> execText() {
        return renaiSearch.searchOperator.search(renaiSearch.module, ops, true, 0, 100);
    }

    public List<RenaiText> execText(int start, int count) {
        return renaiSearch.searchOperator.search(renaiSearch.module, ops, true, start, count);
    }

    public List<String> execId() {
        List<RenaiText> result = renaiSearch.searchOperator.search(renaiSearch.module, ops, false, 0, 100);
        return result.stream().map(RenaiText::getBusinessId).toList();
    }

    public List<String> execId(int start, int count) {
        List<RenaiText> result = renaiSearch.searchOperator.search(renaiSearch.module, ops, false, start, count);
        return result.stream().map(RenaiText::getBusinessId).toList();
    }

}